#include <QVBoxLayout>
#include <QSplitter>
#include <QPushButton>
#include <QSpacerItem>
#include <QCommonStyle>
#include <QAction>

#include "lightControlGuiFactory.h"
#include "QtDmxSliderPanel.h"
#include "QtLightControlPanel.h"
#include "IF_LightEngineInterface.h"
#include "LightPresetModel.h"
#include "ApplicationIcon.h"


/** @class LightControlGuiFactory
 *
 * concrete factory that implements preset list view with
 * Qt Widgets
 */

LightControlGuiFactory::LightControlGuiFactory(int numOfCahnnels, QWidget *parent) :
   QObject(parent),
   m_numOfCahnnels(numOfCahnnels)
{
}

IF_DmxSliderPanel *LightControlGuiFactory::buildDmxSliderPanel(IF_LightEngineInterface *engine,
                                                               IF_LightTransitionEngine *transitionEngine,
                                                               QWidget *parent)
{
   QtDmxSliderPanel *panel = new QtDmxSliderPanel( m_numOfCahnnels, transitionEngine, parent);
   connect( panel, SIGNAL(valueChangedByGUI(double,int)),
            engine, SLOT(setLevelForChannel(double,int)) );
   connect( engine, SIGNAL(dmxStarted()), panel, SLOT(setDmxOn()) );
   connect( engine, SIGNAL(dmxStopped()), panel, SLOT(setDmxOff()) );

   return panel;
}

IF_GuiLightControlPanel *LightControlGuiFactory::buildPresetListViewer( IF_LightEngineInterface *engine,
                                                                        LightPresetModel *model,
                                                                        ActionListController *actionController,
                                                                        QWidget *parent)
{
   Q_ASSERT( actionController != NULL);

   QtLightControlPanel *viewer = new QtLightControlPanel( m_numOfCahnnels, *actionController,
                                                          model, parent);

   connect( viewer, SIGNAL(triggerTransitionRequest(QString)),
            engine, SLOT(triggerTransition(QString)) );
   connect( viewer, SIGNAL(deleteRequest(QString)), model, SLOT(removePreset(QString)) );

   return viewer;
}

void LightControlGuiFactory::buildLightControlPanel( LightPresetModel *model,
                                                     IF_LightEngineInterface *engine,
                                                     IF_DmxSliderPanel *sliderPanel,
                                                     IF_GuiLightControlPanel *presetView,
                                                     QLayout *container)
{
   QSplitter *splitter = new QSplitter( Qt::Vertical, container->parentWidget());
   /* highlight handle */
   splitter->setBackgroundRole( QPalette::Dark );

   QWidget *presetWithToolbar = new QWidget( container->parentWidget());
   presetWithToolbar->setLayout( new QVBoxLayout());
   presetWithToolbar->layout()->setContentsMargins( 2,2,2,2);

   QWidget *toolbar = buildPresetToolbar( model, engine, presetView, container->parentWidget());
   presetWithToolbar->layout()->addWidget( toolbar );
   presetWithToolbar->layout()->addWidget( presetView);
   splitter->addWidget( sliderPanel);
   splitter->addWidget( presetWithToolbar);

   container->addWidget(splitter);
   container->setContentsMargins( 2,2,2,2);
}

QList<QAction *> LightControlGuiFactory::buildActions(IF_GuiLightControlPanel *presetView)
{
   Q_ASSERT( presetView != NULL);

   QAction *triggerTransitionAction = new QAction( tr("trigger active transition"), this);
   triggerTransitionAction->setShortcut( Qt::CTRL | Qt::Key_Space);

   connect( triggerTransitionAction, SIGNAL(triggered()),
            presetView, SLOT(triggerActivePreset()) );

   return QList<QAction *>() << triggerTransitionAction;
}

QWidget *LightControlGuiFactory::buildPresetToolbar( LightPresetModel *model,
                                                     IF_LightEngineInterface *engine,
                                                     IF_GuiLightControlPanel *presetView,
                                                     QWidget *parent)
{
   QCommonStyle style;

   QWidget *toolbar = new QWidget( parent);
   toolbar->setLayout( new QHBoxLayout());
   toolbar->layout()->setContentsMargins( 2,2,2,2);

   /* 'DMX on-off' buttons */
   QPushButton *dmxOnButton = new QPushButton( QIcon(IconPath("light.png")), QString(), toolbar);
   dmxOnButton->setToolTip( tr("turn DMX device on"));
   dmxOnButton->setFocusPolicy(Qt::NoFocus);
   connect( dmxOnButton, SIGNAL(clicked()), engine, SLOT(requestDmxStart()) );
   toolbar->layout()->addWidget( dmxOnButton);

   QPushButton *dmxOffButton = new QPushButton( QIcon(IconPath("no-light.png")), QString(), toolbar);
   dmxOffButton->setToolTip( tr("turn DMX device off"));
   dmxOffButton->setEnabled( false);
   dmxOffButton->setFocusPolicy(Qt::NoFocus);
   connect( dmxOffButton, SIGNAL(clicked()), engine, SLOT(requestDmxStop()) );
   toolbar->layout()->addWidget( dmxOffButton);

   connect( engine, SIGNAL(dmxStartChanged(bool)), dmxOnButton, SLOT(setDisabled(bool)) );
   connect( engine, SIGNAL(dmxStartChanged(bool)), dmxOffButton, SLOT(setEnabled(bool)) );

   /* spacer */
   toolbar->layout()->addItem( new QSpacerItem( 1,1, QSizePolicy::Expanding));

   /* 'create preset' button */
   QPushButton *createButton = new QPushButton( style.standardIcon(QStyle::SP_FileDialogNewFolder),
                                                QString(), toolbar);
   createButton->setFocusPolicy(Qt::NoFocus);
   connect( createButton, SIGNAL(clicked()), model, SLOT(createVoidPreset()) );
   toolbar->layout()->addWidget( createButton);

   /* 'shift up' button */
   QPushButton *shiftUpButton = new QPushButton( style.standardIcon(QStyle::SP_ArrowUp),
                                                 QString(), toolbar);
   shiftUpButton->setToolTip(tr("bring focused element one position above"));
   shiftUpButton->setFocusPolicy(Qt::NoFocus);
   connect( shiftUpButton, SIGNAL(clicked()), presetView, SLOT(shiftFocusedUp()) );
   toolbar->layout()->addWidget( shiftUpButton);

   /* 'shift down' button */
   QPushButton *shiftDownButton = new QPushButton( style.standardIcon(QStyle::SP_ArrowDown),
                                                   QString(), toolbar);
   shiftDownButton->setToolTip(tr("bring focused element one position below"));
   shiftDownButton->setFocusPolicy(Qt::NoFocus);
   connect( shiftDownButton, SIGNAL(clicked()), presetView, SLOT(shiftFocusedDown()) );
   toolbar->layout()->addWidget( shiftDownButton);

   return toolbar;
}

